package entity

import (
	"database/sql/driver"
	"time"
)

type Model struct {
	ID         *uint64   `gorm:"primaryKey;autoIncrement" json:"id"`
	CreateBy   *uint     `json:"createBy" gorm:"create_by"`
	CreateTime time.Time `json:"createTime" gorm:"column:create_time;type:datetime;autoCreateTime"`
	UpdateBy   *uint     `json:"updateBy"  gorm:"update_by"`
	UpdateTime time.Time `json:"updateTime" gorm:"column:update_time;type:datetime;autoCreateTime"`
	IsDeleted  *uint8    `json:"isDeleted" gorm:"is_deleted"`
}

type CommonModel struct {
	CreateBy   *uint   `json:"createBy,omitempty" gorm:"create_by"`
	CreateTime *int64  `json:"createTime,omitempty" gorm:"column:create_time"`
	UpdateBy   *uint   `json:"updateBy,omitempty"  gorm:"update_by"`
	UpdateTime *int64  `json:"updateTime,omitempty" gorm:"column:update_time"`
	DelFlag    *string `json:"delFlag" gorm:"del_flag;default:'0'"`
}

// TimeFormat 时间设置
const TimeFormat = "2006-01-02 15:04:05"

type LocalTime time.Time

func (t *LocalTime) UnmarshalJSON(data []byte) (err error) {
	// 空值不进行解析
	if len(data) == 2 {
		*t = LocalTime(time.Time{})
		return
	}

	// 指定解析的格式
	now, err := time.Parse(`"`+TimeFormat+`"`, string(data))
	*t = LocalTime(now)
	return
}
func (t *LocalTime) MarshalJSON() ([]byte, error) {
	b := make([]byte, 0, len(TimeFormat)+2)
	b = append(b, '"')
	b = time.Time(*t).AppendFormat(b, TimeFormat)
	b = append(b, '"')
	return b, nil
}

// 写入 mysql 时调用
func (t *LocalTime) Value() (driver.Value, error) {
	// 0001-01-01 00:00:00 属于空值，遇到空值解析成 null 即可
	if t.String() == "0001-01-01 00:00:00" {
		return nil, nil
	}
	return []byte(time.Time(*t).Format(TimeFormat)), nil
}

// 检出 mysql 时调用
func (t *LocalTime) Scan(v any) error {
	// mysql 内部日期的格式可能是 2006-01-02 15:04:05 +0800 CST 格式，所以检出的时候还需要进行一次格式化
	//tTime, _ := time.Parse("2006-01-02 15:04:05 +0800 CST", v.(time.Time).String())
	*t = LocalTime(v.(time.Time))
	return nil
}

// 用于 fmt.Println 和后续验证场景
func (t *LocalTime) String() string {
	return time.Time(*t).Format(TimeFormat)
}

func (t *LocalTime) Before(timeArg time.Time) bool {
	return time.Time(*t).Before(timeArg)
}
